//
//  Node.h
//  Sinnca Engine v2
//
//  Created by Ryan Oldis on 6/15/11.
//  Copyright 2011 Sinnca Studios. All rights reserved.
//

#include "global.h"

#include "Texture.h"
#include "Mesh.h"

class node
{
	node* parent;
	std::vector<node*> children;
	
	std::string name;
	std::string behavior;
	
	int noOfChildren;
	bool draw;
	
public:
	
	node();
	virtual ~node();
	
	void callBehavior();
	
	virtual void render() =0;
	
	node* getParent();
	void setParent(node* np);
	void addChild(node* ch);
	void removeChild(node* ch);
	
	friend class scene;
	friend class entity;
	
};

node* checkNode(lua_State* L, int ind);
static int addChild(lua_State* L);
static int removeChild(lua_State* L);

void registerNode(lua_State* L);



enum sceneState
{
	sceneRun,
	scenePause,
	sceneLoad
};

class scene: public node
{
	std::vector<std::string> texList;
	
	std::vector<texture> textureManager;
	// animationManager
	// materialManager
	// meshManager
	// soundManager
	
	float percloaded;
	
	float color[3];
	bool currentPers;
	
	
public:
	
	scene(std::string);
	~scene();
	void load();
	void unload();
	
	void render();
	
	bool pers();
	
	bool loaded;
	bool loadable, unloadable;
	sceneState state;
	
};

scene* checkScene(lua_State* L, int ind);

static int newScene(lua_State* L);
static int switchScene(lua_State* L);

void registerScene(lua_State* L);



class entity: public node
{
	
public:
		
	float xyz[3];
	float rot[3];
	float scl[3];
	
	float color[4];
	
	// material
	texture* tex;
	
	// mesh or sprite
	mesh* m;
	
	entity(std::string, float x = 0.0, float y = 0.0, float z = 0.0, float rx = 0.0, float ry = 0.0, float rz = 0.0, float sx = 40.0, float sy = 40.0, float sz = 1.0, float r = 1.0, float g = 1.0, float b = 1.0, float a = 1.0, bool d = true, texture* t = NULL, mesh* ob = NULL);
	
	
	void render();
	
};

entity* checkEntity(lua_State* L, int ind);

static int newEntity(lua_State* L);
static int setG(lua_State* L);
static int setR(lua_State* L);
static int setS(lua_State* L);

static int setCol(lua_State* L);
static int setTex(lua_State* L);

static int movG(lua_State* L);
static int movR(lua_State* L);
static int movS(lua_State* L);

void registerEntity(lua_State* L);


#define tree (Tree::Instance())
class Tree
{
	scene** root;
	
public:
	
	
	scene* currentScene;
	scene** getRoot();
	
	Tree();
	void setup(lua_State* L);
	
	void setCurScene(scene* sn);
	
	static Tree* Instance();
	
protected:
	
	static Tree* _instance;
	
};

//void registerTree(lua_State* L);



